package syntaxcolor.v4.syntaxcolor.rule;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.swt.custom.StyleRange;

import syntaxcolor.v4.syntaxcolor.scanner.Scanner;
import syntaxcolor.v4.syntaxcolor.token.Token;

/**
 * 关键字规则，完全匹配
 * 
 * @author wyl
 */
public class WordRule implements IRule {

	private String name = null;

	private Set<String> words = new HashSet<String>();

	private String endStr = "";

	private boolean isCaseSenstive = true;

	private StyleRange style;

	public WordRule(String name, String endStr, boolean isCaseSenstive,
			StyleRange style, String... words) {
		super();
		this.name = name;
		this.endStr = endStr;
		this.isCaseSenstive = isCaseSenstive;
		this.style = style;
		addWord(words);
	}

	public WordRule(String name, boolean isCaseSenstive, StyleRange style,
			String... words) {
		// 指定关键字的分隔符，分隔符不可能是关键字的一部分
		this(name, " \n\r\t()[]{};:'\",<.>/\\|`~!@#%^&*+-=", isCaseSenstive,
				style, words);
	}

	public void addWord(String... ws) {
		for (String word : ws) {
			if (!isCaseSenstive) {
				words.add(word.toUpperCase());
			} else {
				words.add(word);
			}

		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see syntaxcolor.v2.IRule#evaluate(syntaxcolor.v2.Scanner)
	 */
	public Token evaluate(Scanner scanner) {
		StringBuffer sb = new StringBuffer();
		int offset = scanner.getOffset();
		char prefixChar = 0;
		// 首先看当前字符前一个字符是否分隔符，如果不是，则当前字符不可能是关键字的开始
		if (scanner.unread()) {
			prefixChar = (char) scanner.read();
		}
		if (prefixChar > 0 && endStr.indexOf(prefixChar) < 0) {
			return null;
		}
		int ch = scanner.read();
		// 找到下一个分隔符，得到中间的字符串
		while (ch > 0 && (endStr.indexOf(ch) < 0)) {
			sb.append((char) ch);
			ch = scanner.read();
		}
		String result = sb.toString();
		if (!"".equals(result)) {
			// 看字符串是否属于关键字
			if ((!isCaseSenstive && words.contains(result.toUpperCase()))
					|| (isCaseSenstive && words.contains(result))) {
				scanner.unread();
				return new Token(offset, result.length(), name);
			}
		}
		scanner.setOffset(offset);
		return null;
	}

	public StyleRange getStyle() {
		return this.style;
	}

	/**
	 * get name value
	 * 
	 * @return name
	 */
	public String getName() {
		return name;
	}

}
